/*
 * Menu: Actionscript > Generate Properties
 * Key: M3+1
 * DOM: http://download.eclipse.org/technology/dash/update/org.eclipse.eclipsemonkey.lang.javascript
 * Author: Igor Wojda (Panel)
 * Author Homepage: http://www.panellabs.voyda.eu
 * Version: 1.0
 */
 
function main() 
{
  var editor = editors.activeEditor;
  var source = editor.source;
  
  if (editor.selectionRange)
  {
		var range  = editor.selectionRange;
		var text = getText(editor);
		var variablesData = getVariablesData(text);
		
		if (variablesData.length > 0)
		{
			var tabulators = getTabulators(getNUmberOfTabulators(editor));
			
			var variablesDeclarationCode = ""
			for (var i = 0, n = variablesData.length; i < n; ++i)
			{
				variablesDeclarationCode += (tabulators + getVariableDeclaration(variablesData[i]));
				if(i < variablesData.length - 1)
					variablesDeclarationCode += "\n";
			}
			
			editor.applyEdit(getLinesBeginOffset(editor), getRangeLength(editor), variablesDeclarationCode);		
			
			var variableGettersSetters = "\n"
			for (var i = 0, n = variablesData.length; i < n; ++i)
			{
				variableGettersSetters += getSettersGettersCode(variablesData[i]);
				if(i < variablesData.length - 1)
					variableGettersSetters += "\n";
			}
			
			variableGettersSetters += "\n";
			
			//alert(variableGettersSetters)
			editor.applyEdit(getClassLatLine(editor), 0, variableGettersSetters);
		}
		else
			alert("Generate Properties input error! \n\nYou have to select pair\\pairs name:Type or put cursor in line containing such pair ex. \n\n age:Number \n name:String");
   }  
}


function getTabulators(number)
{
	var tabulators = "";
	
	for(var i=0; i<number; i++)
	{
		tabulators += "\t";
	}
	
	return tabulators;
}

function getNUmberOfTabulators(editor)
{
	var tabulatorCharCode = "9";
	var beginOffsett = getLinesBeginOffset(editor);
	numberOfTabulators = 0;
	
	for(var i=beginOffsett; i<editor.source.length; i++)
	{
		if(editor.source.charCodeAt(i) == tabulatorCharCode)
			numberOfTabulators++;
		else
			break;
	}
	
	return numberOfTabulators;
}

function getLastClassLineBeginOffset(editor)
{
	var offsetAtTheEndOfClass = getClassLatLine(editor);
	
	for(var i=offsetAtTheEndOfClass; i>0; i--)
	{
		if(isNewLineCharacter(editor.source.charAt(i)))
		{
			offsetAtTheEndOfClass = i;
				break;
		}
	}
	
	return offsetAtTheEndOfClass;
}

function getClassLatLine(editor)
{
	var classKeyrordIndex = editor.source.indexOf(" class ");
	var startIndex = editor.source.indexOf("{", classKeyrordIndex);
	var numBrackets = 0;
	var closingBracketOffset;
	
	for(var i=startIndex; i<editor.source.length; i++)
	{
		if(editor.source.charAt(i) == "{")
			numBrackets++;
		if(editor.source.charAt(i) == "}")
			numBrackets--;
			
		if(numBrackets == 0)
		{
			closingBracketOffset = i-1;
			break;
		}
	}
	
	return closingBracketOffset;
}

function getText(editor)
{
	return editor.source.substring (getLinesBeginOffset(editor), getLinesEndOffset(editor));
}

function getRangeLength(editor)
{
	return getLinesEndOffset(editor) - getLinesBeginOffset(editor)
}

function getVariablesData(str)
{
	var results = str.match(/(\w+:\w+)/g);
	
	if(results)
		return results
	else
		return ""
}

function getVariableDeclaration(v)
{
  var parts = v.split(":");
  
  if (2 != parts.length)
    return "";
  
  var privateTypeName = "_" + parts[0];
  var type = parts[1];
  var typeName = parts[0];
    
  var s = "private var " + privateTypeName + ":" + type + ";";

  return s;
}

function getSettersGettersCode(v)
{
  var parts = v.split(":");
  
  if (2 != parts.length)
    return "";
  
  var privateTypeName = "_" + parts[0];
  var type = parts[1];
  var typeName = parts[0];
  
  var s = "";
  s += "\t\tpublic function set " + typeName + "(val:" + type + "):void";
  s += "\n\t\t{";
  s += "\n\t\t\t" + privateTypeName + " = val;";
  s += "\n\t\t}\n";
  
  
  s += "\n\t\tpublic function get " + typeName + "():" + type;
  s += "\n\t\t{";
  s += "\n\t\t\treturn " + privateTypeName + ";";
  s += "\n\t\t}";
  
  return s;
}

function getEventName (s)
{
	result = s + "Change";
	return result;
}


function getvar(s) {
  if (1 > s.length)
    return "";
    
  return "\n\t\tprotected var _" + s + ";";
}

//returns beginOffset of first selected line. If nothing is selected line with cursor is treated as one selected line
function getLinesBeginOffset(editor)
{
	var enterCharCode = 13;
	var newLineCharCode = 10;
	
	var range = editor.selectionRange
	var currentLineBeginOffset
	
	var test = 0
	
	if(isTextSelected(editor))
	{
		currentLineBeginOffset = range.startingOffset;
		
		for (var i = currentLineBeginOffset; i > 0; i--)
		{
			if(editor.source.charCodeAt(i) == enterCharCode || editor.source.charCodeAt(i) ==  newLineCharCode)
			{
				currentLineBeginOffset = i+1; //beginning of line
				break;
			}
		}
	}
	else
	{
		for (var i = editor.currentOffset-1; i > 0; i--) //if coursor is on the end of line char code==enterCharCode, so currentOffset-1 
		{
			if(editor.source.charCodeAt(i) == enterCharCode || editor.source.charCodeAt(i) ==  newLineCharCode) //beginning of line
			{
				currentLineBeginOffset = i+1;
				
				break;
			}
		}
	}

	return currentLineBeginOffset
}

//returns beginOffset last selected line. If nothing is selected line with cursor is treated as one selected line
function getLinesEndOffset(editor)
{
	var enterCharCode = 13;
	var newLineCharCode = 10;

	var range = editor.selectionRange
	var currentLineEndOffset
	
	if(range.startingOffset == range.endingOffset) //no text selected so return end line offset
	{
		for (var i = editor.currentOffset; i < editor.source.length; i++)
		{
			if(editor.source.charCodeAt(i) == enterCharCode || editor.source.charCodeAt(i) ==  newLineCharCode)
			{
				currentLineEndOffset = i;
				break;
			}
		}
	}
	else
	{
		currentLineEndOffset = range.endingOffset;
	}	
	
	return currentLineEndOffset
}

function isTextSelected(editor)
{
	var range = editor.selectionRange;
	
	if(range.startingOffset == range.endingOffset)
		return false;
	else
		return true;
}

function alert(str)
{
     Packages.org.eclipse.jface.dialogs.MessageDialog.openInformation(window.getShell(), "Monkey Dialog", str)  
}
